package com.mach.platform.service;

import com.google.common.base.Splitter;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.mach.platform.handlers.AvgCarbonFactory;
import com.mach.platform.handlers.EchartFactory;
import com.mach.platform.mapper.YmdStatsMapper;
import com.mach.platform.utils.CloneUtils;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.lang.reflect.InvocationTargetException;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import java.util.stream.Stream;

/**
 * @author Administrator
 * @Description:
 * @Package: com.mach.platform.service
 * @time 2018/9/12 0012 17:12
 */
@Service
public class CarbonServiceImpl {

	@Resource
	private YmdStatsMapper ymdStatsMapper;

	/**
	 * 获取 各能源的  碳排量和 单车碳排量
	 *
	 * @param params
	 * @return
	 */
	public Map carbonCosumed (Map<String, Object> params) {

		Map param = handleParams(params);
		String requetType = params.get("enName").toString();

		int total = 0;

		try {
			Map productionMaps = (Map) CloneUtils.clone(param);
			param.put("etype", "产量");
			param.put("ntype", "实际产量");

			// 查产量
			List<Map> result = ymdStatsMapper.loadProduction(productionMaps);
			 total = result.stream().map(item -> new BigDecimal(item.get("num").toString()))
			                  .reduce(BigDecimal.ZERO, BigDecimal::add).intValue();

		} catch (IllegalAccessException e) {
			e.printStackTrace();
		} catch (InstantiationException e) {
			e.printStackTrace();
		} catch (InvocationTargetException e) {
			e.printStackTrace();
		} catch (NoSuchMethodException e) {
			e.printStackTrace();
		}


		if (requetType.equals("综合产量")) {
			// 统计
			// 返回结果
			Map backResult = Maps.newHashMap();
			backResult.put("carbon", total);
			return backResult;
		}

			if (!requetType.equals("汇总碳排") && !requetType.equals("单车碳排")) {
				// 其他水电类型
				param.put("enName", requetType);
			}
			// 查碳排放 以及消耗量
			Map secondResult = ymdStatsMapper.allCarbon(param);

			// 放 碳排量到结果
			param.put("carbon", secondResult.get("num") == null ? "--" : secondResult.get("num"));
			// 放 消耗量到结果
			param.put("consumption", secondResult.get("comsume") == null ? "--" : secondResult.get("comsume"));

			if (secondResult.get("num") != null && total != 0) {
				param.put("carbonAvg", new BigDecimal(secondResult.get("num").toString())
						                             .divide(new BigDecimal(total), 1, BigDecimal.ROUND_HALF_UP)
						                             .doubleValue());
				if (requetType.equals("单车碳排")) {
					// 为是使前端使用统一 遍历，如果是 单车碳排，则取代 carbon这个统一变量
					param.put("carbon", new BigDecimal(secondResult.get("num").toString())
							                          .divide(new BigDecimal(total), 1, BigDecimal.ROUND_HALF_UP)
							                          .doubleValue());
				}
			}
			if (secondResult.get("comsume") != null && total != 0) {
				param.put("consumptionAvg", new BigDecimal(secondResult.get("comsume").toString())
						                                  .divide(new BigDecimal(total), 1, BigDecimal.ROUND_HALF_UP)
						                                  .doubleValue());
			}

		return param;

	}

	/**
	 * 处理请求参数
	 *
	 * @param params
	 * @return
	 */
	public Map handleParams (Map params) {

		Map result = Maps.newHashMap();

		String timeType = params.get("timeType").toString();
		String timeStr = params.get("dateStr").toString();
		String targettimeStr = params.get("target").toString();
		List<Integer> timeArr = Splitter.on("-").splitToList(timeStr).stream().map(item -> Integer.parseInt(item))
		                                .collect(Collectors.toList());
		List<String> spaceArr = Splitter.on(",").splitToList(targettimeStr);

		// 处理空间参数
		if (spaceArr.size() > 1) {
			for (int i = 1; i < spaceArr.size(); i++) {
				result.put("lv" + i, spaceArr.get(i));
			}
		}

		result.put("factory", result.get("lv1"));
		result.put("workshop", result.get("lv2"));

		// 处理年份参数
		switch (timeType) {
			case "全年份":

				break;

			case "年度":
				result.put("fyear", timeArr.get(0));
				break;

			case "月度":
				result.put("fyear", timeArr.get(0));
				result.put("fmonth", timeArr.get(1));

				break;

			case "日度":
				result.put("fyear", timeArr.get(0));
				result.put("fmonth", timeArr.get(1));
				result.put("fday", timeArr.get(2));
				break;

			default:

				break;
		}

		return result;
	}


	/**
	 * 碳排量趋势 数据
	 *
	 * @param param
	 * @return
	 */
	public Map carbonTrend (Map param) {

		String requetType = param.get("enName").toString();
		Map handledParams = handleParams(param);

		if (!requetType.equals("汇总碳排") && !requetType.equals("单车碳排")) {
			// 其他水电类型
			handledParams.put("enName", requetType);
			handledParams.put("etype", requetType);
		}

		List<Map> dbResult = ymdStatsMapper.carbonTrend(handledParams);

		Map secondParam = null;
		try {
			secondParam = (Map) CloneUtils.deepClone(handledParams);
			secondParam.put("ntype", "计划碳排量");
		} catch (IllegalAccessException e) {
			e.printStackTrace();
		} catch (InstantiationException e) {
			e.printStackTrace();
		} catch (InvocationTargetException e) {
			e.printStackTrace();
		} catch (NoSuchMethodException e) {
			e.printStackTrace();
		}

		List<Map> dbPlanResult = ymdStatsMapper.carbonPlanTrend(secondParam);

		EchartFactory echartFactory = new EchartFactory(param.get("timeType").toString(),
				param.get("dateStr").toString(), dbResult, dbPlanResult);

		return echartFactory.work();

	}

	/**
	 * 单车 碳排量 趋势
	 * @param param
	 * @return
	 */
	public Map carbonTrendAvg (Map param) {

		String requetType = param.get("enName").toString();
		Map handledParams = handleParams(param);

		List<Map> originActPro = null;
		List<Map> originPlanPro = null;

		Map productionParams = null;
		try {
			 productionParams = (Map) CloneUtils.clone(handledParams);
			productionParams.put("etype", "产量");
			productionParams.put("ntype", "实际产量");

			System.out.println("查询参数是：" + productionParams);
			// 查实际产量
			originActPro = ymdStatsMapper.loadProduction(productionParams);

			Map productionParams2 = (Map) CloneUtils.clone(productionParams);
			productionParams2.put("ntype", "计划产量");
			// 查 计划产量
			originPlanPro = ymdStatsMapper.loadProduction(productionParams2);

		} catch (IllegalAccessException e) {
			e.printStackTrace();
		} catch (InstantiationException e) {
			e.printStackTrace();
		} catch (InvocationTargetException e) {
			e.printStackTrace();
		} catch (NoSuchMethodException e) {
			e.printStackTrace();
		}

		if(!requetType.equals("汇总碳排") && !requetType.equals("单车碳排")) {
			// 其他水电类型
			handledParams.put("enName", requetType);
			handledParams.put("etype", requetType);
		}

		// 实际碳排量 数据
		List<Map> dbResult = ymdStatsMapper.carbonTrend(handledParams);
		List<Map> dbResultPlanUse = null;

		try {
			Map planUseParam = (Map) CloneUtils.clone(handledParams);
			planUseParam.put("ntype", "计划碳排量");
			dbResultPlanUse = ymdStatsMapper.carbonPlanTrend(planUseParam);

		} catch (IllegalAccessException e) {
			e.printStackTrace();
		} catch (InstantiationException e) {
			e.printStackTrace();
		} catch (InvocationTargetException e) {
			e.printStackTrace();
		} catch (NoSuchMethodException e) {
			e.printStackTrace();
		}

		AvgCarbonFactory echartFactory = new AvgCarbonFactory(param.get("timeType").toString(),
				param.get("dateStr").toString(), dbResult, dbResultPlanUse,originActPro,originPlanPro);

		return echartFactory.work();

	}


	/**
	 * 获取 碳排量子级 占比数据
	 *
	 * @param param
	 * @return
	 */
	public Map carbonSubset (Map param) {

		Map reulstMap = Maps.newHashMap();

		List<String> spaceLevel = Splitter.on(",").splitToList(param.get("target").toString());
		Map params = handleParams(param);

		String requetType = param.get("enName").toString();

		if (!requetType.equals("汇总碳排") && !requetType.equals("单车碳排")) {
			// 其他水电类型
			params.put("enName", requetType);
		}

		// 加载数据库数据
		List<Map> dbResult = ymdStatsMapper.carbonSubset(params);
		if (dbResult.size() == 0) {
			reulstMap.put("data", Collections.emptyList());
			reulstMap.put("legend", Collections.emptyList());
			return reulstMap;
		}

		if (dbResult.size() ==1 && dbResult.get(0).get("lv"+(spaceLevel.size()))==null){
			Map res = dbResult.get(0);
			reulstMap.put("data", Stream.of(res.get("num")).collect(Collectors.toList()));
			reulstMap.put("legend", Stream.of(res.get("lv" + ( spaceLevel.size() - 1 ))).collect(Collectors.toList()));
			return reulstMap;
		}

		List<Map> handlerData = dbResult.stream().map(item -> {
			Map newMap = Maps.newHashMap();
			newMap.put("name", item.get("lv"+spaceLevel.size()));
			newMap.put("value", item.get("num") == null ? 0 : item.get("num"));
			return newMap;
		}).sorted((o1, o2) -> new BigDecimal(o2.get("value").toString()).subtract(new BigDecimal(o1.get("value").toString())).intValue()).collect(Collectors.toList());

		reulstMap.put("data", handlerData);

		List<Object> legendResult = handlerData.stream().map(map -> map.get("name")).collect(Collectors.toList());

		reulstMap.put("legend", legendResult);
		reulstMap.put("title", spaceLevel.get(spaceLevel.size() - 1) + " " + getTimeStr(param.get("dateStr").toString(),
				param.get("timeType").toString()) + " 子级碳排占比");

		return reulstMap;
	}

	/**
	 * 获取 单车碳排量子级 占比数据
	 * @param param
	 * @return
	 */
	public Map avgCarbonSunset (Map param) {

		Map reulstMap = Maps.newHashMap();

		Map params = handleParams(param);

		String requetType = param.get("enName").toString();

		List<String> spaceLevel = Splitter.on(",").splitToList(param.get("target").toString());

		if (!requetType.equals("汇总碳排") && !requetType.equals("单车碳排")) {
			// 其他水电类型
			params.put("enName", requetType);
		}
		// 加载数据库数据
		List<Map> dbResult = ymdStatsMapper.carbonSubset(params);
		if (dbResult.size() == 0) {
			reulstMap.put("data", Collections.emptyList());
			reulstMap.put("legend", Collections.emptyList());
			return reulstMap;
		}

		List<Map> originActPro = null;

		try {
			Map productionParams = (Map) CloneUtils.clone(params);
			productionParams.put("etype", "产量");
			productionParams.put("ntype", "实际产量");
			// 查实际产量
			originActPro = ymdStatsMapper.loadProductionForSubset(productionParams);

		} catch (IllegalAccessException e) {
			e.printStackTrace();
		} catch (InstantiationException e) {
			e.printStackTrace();
		} catch (InvocationTargetException e) {
			e.printStackTrace();
		} catch (NoSuchMethodException e) {
			e.printStackTrace();
		}

		List<Map> yData = Lists.newArrayList();

		// 简单处理，假设双方的数据长度都一样
		if (dbResult.size() == originActPro.size()) {

			for (int i = 0; i < originActPro.size(); i++) {

				Double curProds = Double.parseDouble(originActPro.get(i).get("num").toString());
				Map saveObj = new HashMap();
				saveObj.put("name", originActPro.get(i).get("lv" + spaceLevel.size()));
				if (curProds.equals(0D)) {
					saveObj.put("value", 0);
				}else {
					saveObj.put("value", new BigDecimal(dbResult.get(i).get("num").toString()).divide(new BigDecimal(curProds),1,
							RoundingMode.HALF_UP));
				}

				yData.add(saveObj);
			}

			// 把结果从大到小排序
			List<Map> sortYdata = yData.stream().sorted((o1, o2) -> new BigDecimal(o2.get("value").toString())
					       .subtract(new BigDecimal(o1.get("value").toString())).intValue()).collect(Collectors.toList());

			reulstMap.put("data", sortYdata);

			List<Object> legendResult = sortYdata.stream().map(map -> map.get("name")).collect(Collectors.toList());

			reulstMap.put("legend", legendResult);
			reulstMap.put("title", spaceLevel.get(spaceLevel.size()-1)+ " " +getTimeStr(param.get("dateStr").toString(),param.get("timeType").toString())+" 子级单车碳排");

		}



		return reulstMap;
	}

	/**
	 * 获取 汇总 类型占比数据
	 * @param param
	 * @return
	 */
	public Map carbonType(Map param){

		Map reulstMap = Maps.newHashMap();

		Map params = handleParams(param);

		String requetType = param.get("enName").toString();

		List<String> spaceLevel = Splitter.on(",").splitToList(param.get("target").toString());

		if (requetType.equals("汇总碳排")) {
			// 其他水电类型
			List<Map> dbResult = ymdStatsMapper.loadEnTypeData(params);
			if (dbResult.size()>0){
				List<Map> handlerDatas = dbResult.stream().map(iitem -> {
					Map saveObj = Maps.newHashMap();
					saveObj.put("name", iitem.get("enName"));
					saveObj.put("value", iitem.get("num"));
					return saveObj;
				}).collect(Collectors.toList());

				reulstMap.put("data", handlerDatas);
				List<Object> legendResult = handlerDatas.stream().map(map -> map.get("name")).collect(Collectors.toList());
				reulstMap.put("legend", legendResult);
				reulstMap.put("title",
						spaceLevel.get(spaceLevel.size() - 1) + " " + getTimeStr(param.get("dateStr").toString(),
								param.get("timeType").toString()) + " 能源类型碳排占比");

			}



		} else {
			// 其他水电 具体类型  暂时无数据判断 返回空盒子
			reulstMap.put("data", Stream.of(0,0,0,0,0,0));
			reulstMap.put("legend", Stream.of("水","电","燃气","蒸汽","压缩空气","冷量"));
			reulstMap.put("title", "无具体数据支持");
/*
			reulstMap.put("title",
					spaceLevel.get(spaceLevel.size() - 1) + " " + getTimeStr(param.get("dateStr").toString(),
							param.get("timeType").toString()) + " 类型碳排占比");
*/

		}

		return reulstMap;
	}


	public String getTimeStr (String date,String timeType ) {

		String result = "";

		switch (timeType) {
			case "全年份":
				result = timeType;
				break;

			case "年度":
				result = date.substring(0, 4) +"年";
				break;
			case "月度":
				result = date.substring(5, 7) +"月";

				break;
			case "日度":
				result = date.substring(8, 10) + "日";
				break;
			default:
				break;
		}

		return result;
	}

}
